package cn.hg.jbsa.admin.interceptor;

import java.net.InetAddress;
import java.net.UnknownHostException;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;

import cn.hg.jbsa.admin.controller.BaseJbsaAdminController;
import cn.hg.jbsa.admin.model.JbsaAdmin;
import cn.hg.jbsa.admin.model.JbsaLogAction;
import cn.hg.jbsa.common.annotation.JbsaLog;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.ObjectUtil;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import io.jboot.Jboot;
import io.jboot.utils.RequestUtil;

/**
 * @author 胡高
 * @date 2022/04/26
 */
public class JbsaLogInterceptor implements Interceptor {

    private void createLog(JbsaLog log, Invocation inv, DateTime now, int executionTime)
        throws UnknownHostException {
        // 创建日志记录
        JbsaLogAction logAction = new JbsaLogAction();

        JbsaAdmin admin = this.getAdmin(inv.getController());
        // 获取UserAgent
        UserAgent userAgent =
            UserAgent.parseUserAgentString(RequestUtil.getUserAgent(inv.getController().getRequest()));
        // 获取浏览器对象
        Browser browser = userAgent.getBrowser();
        // 获取操作系统对象
        OperatingSystem operatingSystem = userAgent.getOperatingSystem();

        logAction.setAdminId(ObjectUtil.isNull(admin) ? null : admin.getId());
        logAction.setClientIp(RequestUtil.getIpAddress(inv.getController().getRequest()));
        logAction.setServerIp(InetAddress.getLocalHost().getHostAddress());
        logAction.setActionName(log.value());
        logAction.setUri(RequestUtil.getCurrentUrl(inv.getController().getRequest()));
        logAction.setActionTime(now);
        logAction.setExecutionTime(executionTime);
        logAction.setQueryString(inv.getController().getRequest().getQueryString());
        logAction.setParams(inv.getController().getKv().toJson());
        logAction.setSessionId(inv.getController().getRequest().getSession().getId());
        logAction.setReferer(RequestUtil.getReferer(inv.getController().getRequest()));

        logAction.setBrowser(browser.getName());
        logAction.setBrowserType(browser.getBrowserType().getName());
        logAction.setBrowserGroup(browser.getGroup().getName());
        logAction.setBrowserManufacturer(browser.getManufacturer().getName());
        logAction.setBrowserRenderingEngine(browser.getRenderingEngine().toString());
        logAction.setBrowserVersion(userAgent.getBrowserVersion().getVersion());
        logAction.setOs(operatingSystem.getName());
        logAction.setOsDeviceType(operatingSystem.getDeviceType().getName());
        logAction.setOsGroup(operatingSystem.getGroup().getName());
        logAction.setOsManufacturer(operatingSystem.getManufacturer().name());

        Jboot.sendEvent("actionLog", logAction);
    }

    private JbsaAdmin getAdmin(Controller controller) {
        if (controller instanceof BaseJbsaAdminController) {
            return ((BaseJbsaAdminController)controller).getCurrentAdmin();
        }

        return null;
    }

    @Override
    public void intercept(Invocation inv) {
        JbsaLog jbsaLog = inv.getMethod().getAnnotation(JbsaLog.class);
        if (jbsaLog == null) {
            inv.invoke();
        } else {

            DateTime now = DateUtil.date();
            // 计时
            TimeInterval timer = DateUtil.timer();

            try {
                inv.invoke();
            } finally {
                try {
                    this.createLog(jbsaLog, inv, now, (int)timer.interval());
                } catch (UnknownHostException e) {
                }
            }
        }
    }

}
